package com.yarolegovich.lovelydialog;

import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.utils.PacMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Created by yarolegovich on 16.04.2016.
 */
public class LovelyChoiceDialog extends AbsLovelyDialog<LovelyChoiceDialog> {
    private static final String KEY_ITEM_CHECKED_STATES = "key_item_checked_states";
    private ListContainer listContainer;
    private Text confirmButton;
    private Context context;

    {
        listContainer = findView(ResourceTable.Id_choices);
    }

    public LovelyChoiceDialog(Context context) {
        super(context);
        this.context = context;
    }

    public LovelyChoiceDialog(Context context, int theme) {
        super(context, theme);
        this.context = context;
    }

    public <T> LovelyChoiceDialog setItems(T[] items, OnItemSelectedListener<T> itemSelectedListener) {
        return setItems(Arrays.asList(items), itemSelectedListener);
    }

    public <T> LovelyChoiceDialog setItems(List<T> items, OnItemSelectedListener<T> itemSelectedListener) {
        ListProvider adapter = new ListProvider(getContext(), items);
        return setItems(adapter, itemSelectedListener);
    }

    public <T> LovelyChoiceDialog setItems(BaseItemProvider adapter, OnItemSelectedListener<T> itemSelectedListener) {
        listContainer.setItemClickedListener(new ItemSelectedAdapter<>(itemSelectedListener));
        listContainer.setItemProvider(adapter);
        return this;
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(T[] items, OnItemsSelectedListener<T> itemsSelectedListener) {
        return setItemsMultiChoice(items, null, itemsSelectedListener);
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(T[] items, boolean[] selectionState, OnItemsSelectedListener<T> itemsSelectedListener) {
        return setItemsMultiChoice(Arrays.asList(items), selectionState, itemsSelectedListener);
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(List<T> items, OnItemsSelectedListener<T> itemsSelectedListener) {
        return setItemsMultiChoice(items, null, itemsSelectedListener);
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(List<T> items, boolean[] selectionState, OnItemsSelectedListener<T> itemsSelectedListener) {
        ListProvider adapter = new ListProvider(getContext(), items);
        adapter.setMulType(true);
        return setItemsMultiChoice(adapter, selectionState, itemsSelectedListener);
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(BaseItemProvider adapter, OnItemsSelectedListener<T> itemsSelectedListener) {
        return setItemsMultiChoice(adapter, null, itemsSelectedListener);
    }

    public <T> LovelyChoiceDialog setItemsMultiChoice(BaseItemProvider adapter, boolean[] selectionState, OnItemsSelectedListener<T> itemsSelectedListener) {
        Text okText = findView(ResourceTable.Id_btn_confirm);
        okText.setVisibility(Component.VISIBLE);
        okText.setClickedListener(new ItemsSelectedAdapter<>(itemsSelectedListener));
        ListContainer choicesList = findView(ResourceTable.Id_choices);
        choicesList.setItemProvider(adapter);
        return this;
    }

    public LovelyChoiceDialog setConfirmButtonText(int text) {
        return setConfirmButtonText(string(text));
    }

    public LovelyChoiceDialog setConfirmButtonText(String text) {
        if (confirmButton == null) {
            throw new IllegalStateException(string(ResourceTable.String_ex_msg_dialog_choice_confirm));
        }
        confirmButton.setText(text);
        return this;
    }

    public LovelyChoiceDialog setConfirmButtonColor(int color) {
        if (confirmButton == null) {
            throw new IllegalStateException(string(ResourceTable.String_ex_msg_dialog_choice_confirm));
        }
        confirmButton.setTextColor(new Color(color));
        return this;
    }

    @Override
    void onSaveInstanceState(PacMap outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    void restoreState(PacMap savedState) {
        super.restoreState(savedState);
    }

    @Override
    protected int getLayout() {
        return ResourceTable.Layout_dialog_choice;
    }

    private class ItemSelectedAdapter<T> implements ListContainer.ItemClickedListener {
        private OnItemSelectedListener<T> adaptee;
        private ItemSelectedAdapter(OnItemSelectedListener<T> adaptee) {
            this.adaptee = adaptee;
        }
        @Override
        public void onItemClicked(ListContainer listContainer, Component component, int position, long id) {
            if (adaptee != null) {
                adaptee.onItemSelected(position, (T) listContainer.getComponentAt(position));
            }
            dismiss();
        }
    }

    public interface OnItemSelectedListener<T> {
        void onItemSelected(int position, T item);
    }

    private class ItemsSelectedAdapter<T> implements Component.ClickedListener {
        private OnItemsSelectedListener<T> adaptee;
        private ItemsSelectedAdapter(OnItemsSelectedListener<T> adaptee) {
            this.adaptee = adaptee;
        }
        @Override
        public void onClick(Component component) {
            if (adaptee != null) {
                Map<Integer, Boolean> checkedItemPositions = ((ListProvider) listContainer.getItemProvider()).getCheckItem();
                List<T> selectedItems = new ArrayList<>(checkedItemPositions.size());
                List<Integer> selectedPositions = new ArrayList<>(checkedItemPositions.size());
                BaseItemProvider adapter = listContainer.getItemProvider();
                for (int index = 0; index < adapter.getCount(); index++) {
                    if (checkedItemPositions.get(index)) {
                        selectedPositions.add(index);
                        selectedItems.add((T) adapter.getItem(index));
                    }
                }
                adaptee.onItemsSelected(selectedPositions, selectedItems);
            }
            dismiss();
        }
    }

    public interface OnItemsSelectedListener<T> {
        void onItemsSelected(List<Integer> positions, List<T> items);
    }
}
